
package com.boot.springBoot.util.threadlocal; 

import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.boot.springBoot.entity.User;
import com.boot.springBoot.encrypt.Base64Util;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * ThreadLocal 将拦截到的用户信息 保存
 * @author Administrator
 *
 */
public class UserUtil {
	
	/** log */
	private static final Logger log = LoggerFactory.getLogger(UserUtil.class);
	
	/** userThreadLocal */
	private static final ThreadLocal<User> USER_THREADLOCAL = new ThreadLocal<User>();
	
	/** token cookie name */
	public static final String TOKEN_COOKIE_NAME = "access-token";
	
	/** userId */
	public static final String USER_ID = "userId";
	
	/** employeeId */ 
	public static final String EMPLOYEE_ID = "employeeId";

	/** EMPLOYEE_NAME */
	public static final String EMPLOYEE_NAME = "employeeName";
	
	/** auccount */
	public static final String ACCOUNT = "account";
	
	/** ORG_ID */
	public static final String ORG_ID = "orgId";
	
	/** ORG_CODE */
	public static final String ORG_CODE = "orgCode";
	
	
	/** ORG_CODE */
	public static final String ORG_NAME = "orgName";
	
	/**
	 * 获取登录用户信息
	 * @param request HttpServletRequest
	 * @return userId
	 */
	private static User createUser(HttpServletRequest request,HttpServletResponse response) {
		String strToken = getToken(request);
//		if(StringUtils.isEmpty(strToken)) {
//			try {
//				System.out.println("执行了没有。。。。。。。。");
//				response.sendRedirect("/web/loginTimeout.html");
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
		User objUser = parseToken(strToken);
		return objUser;
	}

	/**
	 * 从request中获取token 
	 * @param request request
	 * @return token
	 */
	public static String getToken(HttpServletRequest request) {
		// 先从请求header中获取
		String strToken = request.getHeader(TOKEN_COOKIE_NAME);
		if(!StringUtils.isEmpty(strToken)) {
			return strToken;
		}
		// 在从cookie中获取
		return getValueFromCookies(request, TOKEN_COOKIE_NAME);
	}
	
	/**
	 * 解析token获取认证用户信息，并构建成User对象。<br/>
	 * <p>说明：<p>
	 * 该方法被调用的前提是token已经通过client（如：GatewayAuthFilter）的有效校验，故此处解析token不会验证token的有效性，只是获取认证信息而已。
	 * @param token token
	 * @return User
	 */
	private static User parseToken(String token) {
		Map<String, Object> objTokenClaims = parseTokenWithoutKey(token);
		if(objTokenClaims == null) {
			return null;
		}
		User objUser = new User();
//		objUser.setEmployeeId((String)objTokenClaims.get(EMPLOYEE_ID));
//		objUser.setEmployeeName((String)objTokenClaims.get(EMPLOYEE_NAME));
//		objUser.setAccount((String)objTokenClaims.get(ACCOUNT));
//		objUser.setUserId((String)objTokenClaims.get(USER_ID));
//		objUser.setOrgId((String)objTokenClaims.get(ORG_ID));
//		objUser.setOrgName((String)objTokenClaims.get(ORG_NAME));
//		objUser.setOrgCode((String)objTokenClaims.get(ORG_CODE));
		return objUser;
	}
	
	/**
	 * 不验证签名获取token中Claims
	 * @param token token
	 * @return Claims
	 */
	@SuppressWarnings("unchecked")
	private static Map<String, Object> parseTokenWithoutKey(String token) {
		
		if(token == null || "".equals(token)) {
			return null;
		}
		
		try {
			String strTokenClaims = token.split("\\.")[1];
			String strCalimsJson = Base64Util.bcDecoder(strTokenClaims);
			ObjectMapper objMapper = new ObjectMapper();
			return objMapper.readValue(strCalimsJson, Map.class);
		} catch (Exception e) {
			log.error("解析token发生错误。token={}", token, e);
			return null;
		}
	}

	/**
	 * 从cookie中获取对应值
	 * @param request HttpServletRequest
	 * @param cookieName cookieName
	 * @return value
	 */
	private static String getValueFromCookies(HttpServletRequest request, String cookieName) {
		Cookie[] objCookies = request.getCookies();
		if(objCookies == null) {
			return null;
		}
		
		for(Cookie objCookie : objCookies) {
			if(cookieName.equals(objCookie.getName())) {
				return objCookie.getValue();
			}
		}
		return null;
	}

	/**
	 * set Login UserId
	 * @param request HttpServletRequest
	 */
	public static void setUser(HttpServletRequest request,HttpServletResponse response) {
		User objUser = createUser(request,response);
		log.debug("创建登录用户{}", objUser);
		USER_THREADLOCAL.set(objUser);
	}
	
	
	/**
	 * 
	 * @return 登录用户
	 */
	public static String getUserId() {
		User objUser = getUser();
		// 从token中获取当前用户相关信息
		if(objUser != null) {
			return objUser.getId();
		}
		return null;
	}
	
	/**
	 * @return 登录用户
	 */
	public static User getUser() {
		return USER_THREADLOCAL.get();
	}
	
	/**
	 * 清除存储在当前线程中的登录用户信息
	 */
	public static void clear() {
		log.debug("移除登录用户{}", getUser());
		USER_THREADLOCAL.remove();
	}
}
